package br.com.menosehmais.framework.util;

import br.com.menosehmais.framework.loggin.StackTraceLogger;
import br.com.menosehmais.framework.persistence.DomainObjectDTO;
import java.util.LinkedList;
import java.util.List;

import br.com.menosehmais.framework.persistence.DomainObject;
import java.lang.reflect.Constructor;
import java.util.Collection;

public class CollectionUtil {

    /**
     * Obtem uma lista contendo apenas os elementos do tipo passado em entity, ou elementos que herdam do mesmo.
     *
     * @param <DO> Define o tipo da classe para a entity base.
     * @param list Lista contendo os elementros encontrados pela SearchEngine ou similares.
     * @param entity Define a classe base para a lista a ser retornada.
     * @return Sub-lista encontrada.
     */
    public static <DO extends DomainObject> List<DO> subList(List<? extends DomainObject> list, Class<DO> entity){
        List<DO> sub = new LinkedList<DO>();
        for(Object obj : list){
            if(obj.getClass().isAssignableFrom(entity)){
                sub.add((DO)obj);
            }
        }
        return sub;
    }

    public static <DO extends DomainObject, DTO extends DomainObjectDTO<DO>>  List<DTO> convert( List<DO> domainObjectList, Class<DO> domainObjectClass, Class<DTO> dataTransferObjectClass ) throws Exception{
        List<DTO> list = new LinkedList<DTO>();

        Constructor<DTO> dtoConstructor = dataTransferObjectClass.getConstructor(domainObjectClass);

        for(DO obj : domainObjectList){
            list.add( dtoConstructor.newInstance(obj) );
        }

        return list;
    }
    
    public static <DO extends DomainObject> List<String> extractIdList( List<DO> domainObjectList ) {
        List<String> extractedIdList = new LinkedList<String>();
        
        for(DO domainObject : domainObjectList) {
            try {
                String id = domainObject.getId();
                if( !(id.isEmpty()) ) {
                    extractedIdList.add(id);
                }
            } catch (NullPointerException npe) {
                StackTraceLogger.INSTANCE.printStackTrace(npe);
            }
        }
        
        return extractedIdList;
    }
    
    /**
     * Null Safe
     * @param collection
     * @return true se a coleção for nula ou se estiver vazia, caso contrário retorna false
     */
    public static boolean isEmpty(Collection collection) {
        if(collection == null) {
            return true;
        }
        return collection.isEmpty();
    }
    
    /**
     * Null Safe
     * @param collection
     * @return false se a coleção for nula ou se estiver vazia, caso contrário retorna true
     */
    public static boolean isNotEmpty(Collection collection) {
        return !(isEmpty(collection));
    }
}
